#!/bin/sh

CC=aarch64-linux-gnu-

TOP_DIR=$(dirname $(readlink -f "$0"))
export PWD
KERNEL_DIR=${TOP_DIR}/kernel/linux
INCLUDE_DIR=${TOP_DIR}/drivers/dev_inc
LIBC_SEC_DIR=${TOP_DIR}/libc_sec
DRV_DIR=${TOP_DIR}/drivers/dev_plat
EXTRA_SYMBOLS=

PARA2=$2
PARA3=$3
HEADER_TYPE=${PARA3}
OUTPUT=${TOP_DIR}/output
OUTPUT_RAW=${OUTPUT}/out_raw
OUTPUT_HEAD=${OUTPUT}/out_header
OUTPUT_REPACK=${OUTPUT}/repack
SCRIPTS_DIR=${TOP_DIR}/scripts

DRIVER_MODULES="cpld devdrv/pcie_host dfm eeprom fandrv mdio hdc_host higmac i2c_slave lsw nor_flash PCA6416 pwm_drv sgpio spi pcie_mcc_host watchdog"

usage ()
{
	echo "[Usage]: "
	echo "[Kernel]"
	printf "%-50s%-50s\n" "	./build.sh kernel" "#build kernel, default version 0.0.0.0.0"
	printf "%-50s%-50s\n" "	./build.sh kernel [version]" "#build kernel, version such as x.x.x.x.x"
	printf "%-50s%-50s\n" "	./build.sh dtb" "#build dtb, default version is 0.0.0.0.0"
	printf "%-50s%-50s\n" "	./build.sh dtb [version]" "#build dtb, version such as x.x.x.x.x"
	printf "%-50s%-50s\n" "	./build.sh modules" "#build kernel modules"
	printf "%-50s%-50s\n" "	Note: the firmware version must less then <FFF.FFF.FFF.FFF.FFF>"

	echo "[MiniRC]"
	printf "%-50s%-50s\n" "	./build.sh minirc" "#build mini modules"
	printf "%-50s%-50s\n" "	./build.sh [name]" "#build mini module name; eg: ./build.sh mdio"

	echo "[Repack]"
	printf "%-50s%-50s\n" "	./build.sh repack [src package path]" "#repack package; eg: ./build.sh repack ../Ascend310-driver-<version>-ubuntu18.04.aarch64-minirc.tar.gz"
	exit
}

compile_patch ()
{
	sed -i '/LOCALVERSION/ s#\"\"#\"+\"#' ${KERNEL_DIR}/arch/arm64/configs/mini_defconfig
}

compile_dep_modules ()
{
	KBUILD_EXTRA_SYMBOLS_VAL=
	if [ -f $DRV_DIR/$1/module.mk ]; then
		modules_dep=`cat $DRV_DIR/$1/module.mk |  grep LOCAL_DEPEND_KO | awk -F = '{ print $2 }' | sed 's/drv_/ /g'`
		#for dep in ${modules_dep[@]}
		for dep in ${modules_dep}
		do
			if [ $dep = pcie_host ]; then
				dep=devdrv/${dep}
			fi
			if [ -d ${DRV_DIR}/${dep} ]; then
				compile_modules ${dep} modules
				KBUILD_EXTRA_SYMBOLS_VAL+="${DRV_DIR}/${dep}/Module.symvers "
			fi
		done
	fi
	echo $KBUILD_EXTRA_SYMBOLS_VAL
}

compile_kernel ()
{
	make -C ${KERNEL_DIR} distclean
	make -C ${KERNEL_DIR} ARCH=arm64 CROSS_COMPILE=${CC} mini_defconfig
	make -C ${KERNEL_DIR} ARCH=arm64 CROSS_COMPILE=${CC} $1 -j16
	if [ $? -ne 0 ]; then
		echo "Compile $1 failed"
		exit 1
	fi
	echo "Compile $1 success"

#	if [ $1 == "Image" ]; then
		cp -f ${KERNEL_DIR}/arch/arm64/boot/Image ${OUTPUT_RAW}/Image_raw
		echo "raw component path: ${OUTPUT_RAW}"

		${SCRIPTS_DIR}/header.sh add ${OUTPUT_RAW}/Image_raw ${OUTPUT_HEAD}/Image $2 ${HEADER_TYPE}
		echo "header component path: ${OUTPUT_HEAD}"
#	fi
}

compile_modules ()
{
	make KBUILD_MODPOST_FAIL_ON_WARNINGS=1 KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS_VAL" ARCH=arm64 CROSS_COMPILE=${CC} -C ${KERNEL_DIR} M=${DRV_DIR}/$1 $2
	if [ $? -ne 0 ]; then
		echo "Compile $1 failed"
		exit 1
	fi
	if [ $2 = "modules" ]; then
		cp -rf ${DRV_DIR}/$1/*.ko $OUTPUT/
		echo "Compile $1 success"
	else
		echo "Clean $1 success"
	fi
}

compile_dtb ()
{
	#make -C ${KERNEL_DIR} distclean
	#make -C ${KERNEL_DIR} ARCH=arm64 CROSS_COMPILE=${CC} mini_defconfig
	${SCRIPTS_DIR}/make_dtb.sh ${TOP_DIR}
	if [ $? -ne 0 ]; then
		echo "Compile dtb failed"
		exit 1
	fi
	echo "raw component path: ${OUTPUT_RAW}"

	${SCRIPTS_DIR}/header.sh add ${OUTPUT_RAW}/dt_raw.img ${OUTPUT_HEAD}/dt.img $1 ${HEADER_TYPE}
	echo "header component path: ${OUTPUT_HEAD}"
}

change_mode ()
{
	chmod +x -R ${SCRIPTS_DIR}
}

repack_package ()
{
	${SCRIPTS_DIR}/minirc_repack.sh $1
	if [ $? -ne 0 ]; then
		echo "Repack failed"
		exit 1
	fi
	echo "repack package path: ${OUTPUT_REPACK}"
}

default_ver ()
{
	if [ ! ${PARA2} ]; then
		PARA2="0.0.0.0.0"
	fi
}

check_cert ()
{
	if [ ! ${PARA3} ]; then
		HEADER_TYPE="fake"
	fi
}

check_arch()
{
	if [[ `uname -i` =~ "aarch" ]]; then
		CC=
	fi
}

if [ $# -lt 1 ]; then
	usage
fi

if [ ! -d ${OUTPUT} ]; then
	mkdir ${OUTPUT}
fi

if [ ! -d ${OUTPUT_RAW} ]; then
	mkdir ${OUTPUT_RAW}
fi

if [ ! -d ${OUTPUT_HEAD} ]; then
	mkdir ${OUTPUT_HEAD}
fi

check_arch
change_mode
compile_patch
case $1 in
	"minirc" | "clean")
		#for drv_module in ${DRIVER_MODULES[@]}
		for drv_module in ${DRIVER_MODULES}
		do
			if [ -d ${DRV_DIR}/${drv_module} ]; then
				if [ $1 = "clean" ]; then
					compile_modules ${drv_module} clean
				else
					compile_dep_modules ${drv_module}
					compile_modules ${drv_module} modules
				fi
			fi
		done
		;;
	"kernel")
		check_cert
		default_ver
		compile_kernel Image ${PARA2}
		;;
	"modules")
		compile_kernel modules
		;;
	"dtb")
		check_cert
		default_ver
		compile_dtb ${PARA2}
		;;
	"repack")
		echo ${PARA2}
		repack_package ${PARA2}
		;;
	*)
		if [ -d ${DRV_DIR}/$1 ]; then
			compile_dep_modules $1
			compile_modules $1 modules
		else
			usage
		fi
		;;
esac


